const nodeHtmlToImage = require('node-html-to-image');
const cheerio = require('cheerio');

module.exports = class HTMLPrint {
  async json2Image(data, options = {}) {
    if (!Array.isArray(data)) {
      throw new Error('only support Array data.');
    }

    const tableString = this.json2table(data, options);
    const outputHTML = this.htmlString(tableString);

    return await nodeHtmlToImage({ html: outputHTML, selector: 'table' });
  }

  json2table(data, option = {
    map: {},
    thead: false
  }) {
    const { map, thead: hasThead } = option;
    const $ = cheerio.load(`<table border="1"></table>`);

    if (hasThead) {
      const thead = $('<thead></thead>');
      const tr = $('<tr></tr>');

      Object.keys(data[0]).forEach(key => {
        const th = $('<th></th>').text(map[key] || key);

        tr.append(th);
      });

      thead.append(tr);
      
      $('table').append(thead);
    }

    const tbody = $('<tbody></tbody>');

    data.forEach(item => {
      const tr = $('<tr></tr>');

      Object.values(item).forEach(value => {
        const td = $('<td></td>').text(value);

        tr.append(td);
      });

      tbody.append(tr);
    });

    $('table').append(tbody);

    const htmlString = $('table').prop('outerHTML');

    return htmlString;
  }

  htmlString(table) {
    const $ = cheerio.load(
      `<html>
        <head></head>
        <body></body>
      </html>`
    );

    $('body').append($(table).prop('outerHTML'));

    $('html').append(`
    <style>
      * {
        margin: 0;
        padding: 0;
        background-color: #ffffff;
        font-size: 14px;
      }

      table { 
        border-color: black;
        border-collapse: collapse;
        width: 400px;
      }

      th {
        text-align: center;
      }
            
      th,td {
        padding: 8px;
      }

      th {
        font-weight: 400;
      }
      
      table tr>td:first-child {
        text-align: center;
        width: 100px;
      }
    </style>
  `);

    return $('html').prop('outerHTML').replace(/\n/g, '');
  }
}